package com.laxcen.basiclib.core.task.core.task;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 任务帮助类（负责任务线程池创建、线程池中任务的添加、移除等操作）
 */
public class TaskHelper {

    private final HashMap<Integer, TaskHandler> CACHE = new HashMap<>();

    private final int mCoreSize;

    //下一次处理塞Task的Handler游标
    private int mNextHandlerCusor;

    public TaskHelper(int coreSize, String groupName, int priority) {
        preAllCoreThread(coreSize, groupName, priority);
        mCoreSize = coreSize;
    }

    /**
     * 预初始化所有核心线程
     * @param coreSize 线程池核心数量
     * @param groupName 线程池名称
     * @param priority 优先级
     */
    private void preAllCoreThread(int coreSize, String groupName, int priority) {
        for (int i = 0; i < coreSize; i++) {
            CACHE.put(i, new TaskHandler(groupName + "  # " + priority + "#" + i, priority));
        }
    }

    /**
     * 添加
     * @param command
     */
    public void add(Runnable command) {
        add(TaskMessage.newBuilder(command).builder());
    }

    /**
     * 添加
     * @param command 任务
     * @param what
     * @param delayTime 延时时间
     * @param priority  优先级
     */
    public void add(Runnable command, int what, int delayTime, int priority) {
        add(TaskMessage.newBuilder(command).what(what).delayTime(delayTime).priority(priority).builder());
    }

    public void add(TaskMessage taskMessage) {
        if (mNextHandlerCusor >= mCoreSize) {
            mNextHandlerCusor = 0;
        }
        TaskHandler handler = CACHE.get(mNextHandlerCusor);
        if (handler == null && mNextHandlerCusor == 0) {
            return;
        }
        if (handler == null) {
            // 如果游标没有对应的handler 则默认用0个游标
            mNextHandlerCusor = 0;
            add(taskMessage);
            return;
        }
        handler.sendMessage(taskMessage);
        mNextHandlerCusor++;
    }

    /**
     * 移除线程池中所有含有tag的消息
     * @param what
     */
    public void removeAllByTag(int what) {
        Set<Map.Entry<Integer, TaskHandler>> entrySet = CACHE.entrySet();
        for (Map.Entry<Integer, TaskHandler> entry : entrySet) {
            TaskHandler handler = entry.getValue();
            if (handler != null) {
                handler.removeMessages(what);
            }
        }
    }

    /**
     * 移除线程池中所有的msg和message
     */
    public void removeCallbacksAndMessages() {
        Set<Map.Entry<Integer, TaskHandler>> entrySet = CACHE.entrySet();
        for (Map.Entry<Integer, TaskHandler> entry : entrySet) {
            TaskHandler handler = entry.getValue();
            if (handler != null) {
                handler.removeCallbacksAndMessages();
            }
        }
    }
}

